<template>
  <div class="pd-body">
    <div class="fa-bars-div" @click="showMainFunc">
      <i class="fa fa-bars" aria-hidden="true"></i>
    </div>

    <!--<div class="" style="position: fixed; top: 0; left: 0; height: 100vh; width: 100vw">
      <iframe src="https://f-pvs.pblandscape.com:8081/?furl=f1617bf8-4eb5-4752-b13c-965619dc2bef.xlsx" frameborder="0"></iframe>
    </div>-->
    <popup v-model="showMain" position="left" should-rerender-on-show>
      <div class="main-box">
        <div class="search-box flex">
          <input type="text" v-model="filterText" placeholder="搜索内容">
          <div class="search-btn" @click="filterTextFunc(filterText)">搜索</div>
        </div>
        <div class="main-title">分类</div>

        <el-tree
          @node-click="handleNodeClick"
          :data="listTree"
          ref="tree"
          node-key="id"
          :default-expanded-keys="openId"
          :filter-node-method="filterNode"
          :props="defaultProps">
          <span class="custom-tree-node" slot-scope="{ node, data }">
            <span class="file-count">{{ data.num }}</span>
            <span>
                  {{ node.label }}
            </span>
          </span>
        </el-tree>

      </div>
    </popup>
    <div class="pj-list-box">
      <div class="pj-items">
        <!--<div class="prj-id fx-bw">
          <h3>项目编号</h3>
          <span>154892156753</span>
        </div>-->
        <div>
          <div class="fx-bw">
            <div class="pj-title line-2">{{ projectInfo.name }}（{{ projectInfo.fileCount }}）</div>
            <div class="pj-state ing">{{ projectInfo.fcontractstate }}</div>
          </div>
          <div class="">
            <div class="flex src-point">
              <div class="tree-src">当前目录：</div>
              <div class="pj-src">
                <span v-for="item in treeList"> {{ item }} /</span>
              </div>
            </div>
            <!--<x-progress :percent="80" class="pj-progress-load" :show-cancel="false"></x-progress>-->
          </div>

          <div class="pj-progress-box">
            <!--<div class="fx-bw">
              <div class="pj-title">项目进度</div>
              <div class="pj-progress-num">已完成</div>
            </div>-->
            <!--<x-progress :percent="80" class="pj-progress-load" :show-cancel="false"></x-progress>-->
          </div>
        </div>
      </div>

      <div class="pj-items">
        <div class="fx-bw dt-title">
          <div class="pj-title search-box2 flex">
            <span>列表</span>
          </div>
          <div class="pj-search">
            <el-input placeholder="搜索文件" v-model="keywords" class="input-with-select">
              <el-button slot="append" icon="el-icon-search" @click="searchFileList"></el-button>
            </el-input>
          </div>
          <div>
            <el-dropdown trigger="click">
              <i class="fa-bars fa" @click="checkCateId"></i>
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item>
                  <div class="up-load-box" @click="showUpload">
                    上传文件
                  </div>
                </el-dropdown-item>
                <!--<el-dropdown-item>下载</el-dropdown-item>
                <el-dropdown-item>搜索</el-dropdown-item>-->
              </el-dropdown-menu>
            </el-dropdown>
          </div>
        </div>
        <!-- <div class="search-input flex">
           <i class="el-icon-search"></i>
           <input type='search' v-model="keyword" onKeyDown="searchFileList()" placeholder="搜索文件"/>
         </div>-->

        <div class="upload-box" v-if="uploadDiv === true">
          <!--            action="http://gcdoc.pblandscape.com:9090/material/file/fileUpload"-->
          <el-upload
            class="upload-demo ul-btn"
            ref="upload"
            :limit="1"
            :data="fileInfo"
            :on-success="uploadOnSuccess"
            :on-error="uploadOnError"
            :on-change="handleChange"
            :on-preview="handlePreview"
            :on-remove="handleRemove"
            :action="actionUpload"
            :file-list="fileUploadList"
            :auto-upload="false">
            <div slot="trigger" class="get-file">选取文件</div>
            <div size="small" type="success" class="upload-file" @click="submitUpload">上传到服务器</div>
          </el-upload>
          <!--<el-upload
            class="upload-demo"
            action="http://gcdoc.pblandscape.com:9090/material/file/fileUpload"
            :on-change="handleChange"
            :file-list="fileUploadList">
            &lt;!&ndash;<div slot="tip" class="el-upload__tip">只能上传jpg/png文件，且不超过500kb</div>&ndash;&gt;
          </el-upload>-->
        </div>

        <div class="pj-dt-list">
          <!--<div class="fx-bw pj-head">
            <div class="pj-info1">文件名称</div>
            <div class="pj-info2">状态</div>
            <div class="">操作</div>
          </div>-->

          <div>
            <scroller v-if="fileList.length > 0 " lock-x height="52vh" @on-scroll-bottom="onScrollBottom"
                      ref="scrollerBottom" :scroll-bottom-offst="200">
              <ul class="file-list">
                <li class="file-item fx-bw" v-for="item in fileList">
                  <div>
                    <div class="file-name" @click="yulan()">{{ item.name }}({{
                      String(Math.ceil(item.fileSize/1000)).replace(/(\d)(?=(\d{3})+$)/g, "$1,") }}kb)<!--&nbsp;&nbsp;<span>点击预览</span>--></div>
                    <div class="file-info">
                      <span>{{ item.owner }}</span>
                      <span>{{ item.lastupdateTime }}</span>
                      <span v-if="item.upLoadStatus === 1"> 上传完毕 </span>
                    </div>
                  </div>
                  <div class="more-icon" @click.stop="getFileid(item.id)"><i class="el-icon-more-outline"></i>
                  </div>
                </li>
              </ul>
              <!--<div class="box2">
                <div class="fx-bw pj-info" v-for="item in fileList">
                  <input class="checkItem" type="checkbox" value="apple" v-model="checkData">
                  <div class="pj-info1">
                    <div class="prj-files">{{ item.name }}（{{ item.fileSize }} kb）</div>
                    <div class="prj-name">{{ item.owner }}</div>
                    <div class="prj-date">{{ item.lastupdateTime }}</div>
                  </div>
                  <div class="pj-info3">正常</div>
                  <div class="pj-info4" @click.stop="getFileHistory(item.fileId)">查看历史（{{ item.historyCount }}）</div>
                </div>
              </div>-->
              <!--<load-more v-if="fileList.length > 0 " tip="loading"></load-more>-->

            </scroller>

            <div v-else class="none-data">
              暂无数据
            </div>
          </div>

          <x-dialog v-model="historyList" class="dialog-demo" hide-on-blur>
            <div class="ht-box">
              <p class="ht-tip">历史操作</p>
              <div class="ht-content">
                <scroller v-if="historyInfo.length > 0 " lock-x height="220px" @on-scroll-bottom="onScrollBottom"
                          ref="scrollerBottom" :scroll-bottom-offst="200">

                  <ul class="file-list" >
                    <li class="file-item fx-bw" v-for="item in historyInfo">
                      <div>
                        <div class="file-name">{{ item.name }}({{ String(Math.ceil(item.fileSize/1000)).replace(/(\d)(?=(\d{3})+$)/g, "$1,") }}kb)<!--&nbsp;&nbsp;<span>点击预览</span>--></div>
                        <div class="file-info">
                          <span>{{ item.owner }}</span>
                          <span>{{ item.lastupdateTime }}</span>
                          <span v-if="item.upLoadStatus === 1">上传完成</span>
                        </div>
                      </div>
                      <!--<div class="more-icon" @click.stop="getFileHistory(item.fileId)"><i class="el-icon-more-outline"></i></div>-->
                    </li>
                  </ul>
                </scroller>
                <div v-else class="no-history">
                  暂无记录
                </div>
              </div>
            </div>
          </x-dialog>

          <!-- 查看历史 -->
          <actionsheet
            v-model="historyShow"
            :menus="menus1"
            @on-click-menu="fileHandle"
          >
            <!--
              @on-after-hide="log('after hide')"
            @on-after-show="log('after show')"
            -->
          </actionsheet>
          <!--重命名提示框-->

          <confirm v-model="renameShow"
                   show-input
                   :title="'文件重命名'"
                   @on-cancel="renameCancel"
                   @on-confirm="renameConfirm"
          >
          </confirm>

          <confirm v-model="fileSrcShow"
                   :title="'请先选择目录'"
                   @on-cancel="fileCancel"
                   @on-confirm="fileConfirm"
          >
          </confirm>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
  import {
    TransferDom,
    Popup,
    Search,
    Actionsheet,
    Cell,
    XProgress,
    XTable,
    LoadMore,
    Scroller,
    XDialog,
    Confirm
  } from 'vux'
  import {baseGet, handleLocalStorage} from '../../../base/baseApi'

  const cityOptions = ['上海', '北京', '广州', '深圳']
  export default {
    directives: {
      TransferDom
    },
    components: {
      Popup,
      Confirm,
      Actionsheet,
      XDialog,
      Scroller,
      Search,
      LoadMore,
      XTable,
      XProgress,
      Cell
    },
    data () {
      return {
        openId: [],
        pageNumber: 1,
        filterText: null,
        treeList: [],
        fileSrcShow: false,
        keywords: null,
        renameShow: false,
        projectInfo: {},
        fileId: 0,
        fileInfo: {
          token: '470d1fa8-66d1-4ff1-a67f-1792687fa65d',
          projectId: this.$route.query.id,
          catalogId: null,
          name: null,
          size: null
        },
        historyInfo: [],
        actionUpload: '',
        srcName: '',
        uploadDiv: false,
        historyList: false,
        fileUploadList: [],
        menus1: ['查看历史', '下载', '重命名', '删除'],
        searchInfo: '',
        historyShow: false,
        fileList: [],
        checkData: [],
        listTree: [],
        defaultProps: {
          children: 'child',
          label: 'name'
        },
        showMain: false,
        // checkAll: false,
        checkedCities: ['上海', '北京'],
        cities: cityOptions,
        isIndeterminate: true,
        show14: false
      }
    },
    mounted () {
      let _this = this
      _this.getlisttree()
      _this.getproject()
      let token = handleLocalStorage('get', 'token')
      _this.fileInfo.token = token
    },
    methods: {
      /*
      * 预览
      * */
      /* async yulan (e) {
        console.log(e)
        let _this = this
        let ret = await baseGet({ furl: 'f1617bf8-4eb5-4752-b13c-965619dc2bef.xlsx', token: _this.fileInfo.token }, 'http://' + window.location.host + '/yulan', _this)
        console.log(ret)
      }, */
      /*
      * 筛选目录关键字
      * */
      filterTextFunc (val) {
        this.$refs.tree.filter(val)
      },
      filterNode (value, data) {
        if (!value) return true
        return data.name.indexOf(value) !== -1
      },
      /*
      * 选择目录
      * */
      fileConfirm () {
        this.showMain = true
      },
      fileCancel () {
      },
      /*
      * 搜索文件
      * */
      searchFileList () {
        let _this = this
        this.getfilelisttopc({catalogId: _this.fileInfo.catalogId, keyword: _this.keywords})
      },
      /*
      * 获取项目信息
      * */
      async getproject () {
        let _this = this
        let res = await baseGet({
          projectId: _this.$route.query.id
        }, 'material/project/getprojectbyid', _this)
        console.log(res)
        _this.projectInfo = res.data
      },
      /*
      * 显示上传组件
      * */
      checkCateId () {
        let _this = this
        if (!_this.fileInfo.catalogId) {
          _this.fileSrcShow = true
        }
      },
      showUpload () {
        let _this = this
        _this.uploadDiv = true
      },
      /*
      * 上传文件
      * */
      handleChange (file) {
        let _this = this
        _this.fileInfo.name = file.name
        _this.fileInfo.size = file.size
        // let projectid = _this.$route.query.id
        _this.actionUpload = `http://gcdoc.pblandscape.com:9090/material/file/fileUpload`
        // http://gcdoc.pblandscape.com:9090/material/file/fileUpload
      },
      submitUpload (data) {
        let _this = this
        this.$refs.upload.submit()
        this.getfilelisttopc({catalogId: _this.fileInfo.catalogId})
      },
      /*
      * 上传成功
      * */
      uploadOnError () {
        this.$message.warning('上传出错！')
      },

      uploadOnSuccess (res) {
        // 图片上传成功
        console.log(res)
        if (res.data.uploadTime) {
          this.$vux.toast.show({type: '', text: '上传成功'})
          this.fileUploadList = []
        } else {
          this.$vux.toast.show({type: 'cancel', text: '上传失败'})
        }
        this.submitUpload()
      },
      handleRemove (file, fileList) {
        console.log(file, fileList)
      },
      handlePreview (file) {
        console.log(file)
      },
      /*
      * 历史菜单
      * */
      fileHandle (key) {
        console.log(key)
        let _this = this
        switch (key) {
          case 0:
            this.historyList = true
            _this.getFileHistory()
            break
          case 1:
            break
          case 2:
            _this.renameShow = true
            break
          case 3:
            _this.deleteFile()
            break
        }
      },
      /*
      * 点击文件操作
      * */
      log (str) {
        console.log(str)
      },
      /*
     * 重命名
     * */
      renameCancel () {
        console.log('on 取消重命名')
      },
      async renameConfirm (msg) {
        let _this = this
        let res = await baseGet({
          fileName: msg,
          id: _this.fileId
        }, 'material/file/updatefileName', _this)
        this.getfilelisttopc({catalogId: _this.fileInfo.catalogId})
        console.log(res)
      },
      /*
      * 历史文件
      * */
      getFileid (id) {
        this.fileId = id
        this.historyShow = true
      },
      async getFileHistory () {
        let _this = this
        let res = await baseGet({
          projectid: _this.$route.query.id,
          fileid: _this.fileId
        }, 'material/file/getfilehistory', _this)
        console.log(res)
        _this.historyInfo = res.data
      },
      /*
      * 删除文件
      * */
      async deleteFile (fileid) {
        let _this = this
        let res = await baseGet({
          projectId: _this.$route.query.id,
          fileId: _this.fileId
        }, 'material/file/deletefile', _this)
        this.getfilelisttopc({catalogId: _this.fileInfo.catalogId})
        console.log(res)
      },
      /*
      * 下拉加载
      * */
      onScrollBottom () {
        let _this = this
        if (this.onFetching) {
          // do nothing
        } else {
          this.onFetching = true
          setTimeout(() => {
            this.pageNumber += 1
            _this.getfilelisttopc({pageNumber: this.pageNumber})
            this.onFetching = false
          }, 1000)
        }
      },
      handleNodeClick (data) {
        let _this = this
        let treeList = _this.treeList
        let level = this.$refs.tree.currentNode.node.level
        let name = this.$refs.tree.currentNode.node.data.name
        treeList[level - 1] = name
        console.log('数组长度====' + treeList.length)
        console.log('当前层级====' + level)
        _this.getfilelisttopc({catalogId: data.id})
        _this.openId[0] = data.id
        console.log(data.id)
        _this.getCatalogInfo(data.id)
        if (level < treeList.length) {
          treeList.splice(level, treeList.length - level)
        }
        console.log(treeList)
      },
      getTreeNode (node) {
        if (node) {
          if (node.label !== undefined) {
            this.breadList.unshift(node.label) // 在数组头部添加元素
            this.getTreeNode(node.parent) // 递归
            // this.breadLabel = this.breadList.join('>')
          }
        }
      },
      checkAll (e) { // 点击全选事件函数
        var checkObj = document.querySelectorAll('.checkItem') // 获取所有checkbox项
        if (e.target.checked) { // 判定全选checkbox的勾选状态
          for (var i = 0; i < checkObj.length; i++) {
            if (!checkObj[i].checked) { // 将未勾选的checkbox选项push到绑定数组中
              this.checkData.push(checkObj[i].value)
            }
          }
        } else { // 如果是去掉全选则清空checkbox选项绑定数组
          this.checkData = []
        }
      },
      showMainFunc () {
        let _this = this
        _this.showMain = true
      },
      /*
      * 获取目录树
      * */
      async getlisttree () {
        let _this = this
        let res = await baseGet({
          projectId: _this.$route.query.id
        }, 'material/catalog/getlisttree', _this)
        console.log(res)
        _this.listTree = res.data
      },
      /*
      * 目录信息
      * */
      async getCatalogInfo (pid) {
        let _this = this
        let res = await baseGet({
          projectId: _this.$route.query.id,
          id: pid
        }, 'material/catalog/getCatalogInfo', _this)
        _this.fileInfo.catalogId = res.data.id
        // _this.srcName += res.data.name + '/'
      },
      /*
      * 文件列表
      * */
      async getfilelisttopc (params = {}) {
        let _this = this
        let { catalogId, keyword, pageNumber } = params
        let res = await baseGet({
          catalogId,
          keyword,
          pageNumber,
          projectId: _this.$route.query.id
        }, 'material/file/getfilelisttopc', _this)
        // console.log(res)
        _this.fileList = res.data.pageInfo.list
      },
      handleCheckAllChange (val) {
        this.checkedCities = val ? cityOptions : []
        this.isIndeterminate = false
      },
      handleCheckedCitiesChange (value) {
        let checkedCount = value.length
        this.checkAll = checkedCount === this.cities.length
        this.isIndeterminate = checkedCount > 0 && checkedCount < this.cities.length
      }
    }
  }
</script>

<style scoped>
  .src-point{
    align-items: center;
  }
  .el-dropdown-menu {
    z-index: 10 !important;
  }
  .no-history{
    text-align: center;
  }
  .tree-src {
    margin-top: 5px;
  }

  .pj-search /deep/ .el-input {
    width: 100%;
    border-radius: 30px;
    overflow: hidden;
    margin-left: 0;
    margin: 10px 0;
    border: 1px solid #e8e8e8;
  }
  .pj-search{
    width: 200px;
  }
  .pj-search /deep/ .el-input-group__append {
    border: none;
  }

  .pj-search /deep/ .el-input__inner {
    height: 30px;
    line-height: 30px;
    border: none;
  }

  .upload-file {
    width: 50%;
    float: right;
    height: 35px;
    background: #04be02;
    color: #fff;
    line-height: 35px;
    text-align: center;
    font-size: 14px;
  }

  .upload-box /deep/ .el-upload {
    width: 50%;
    height: 35px;
    background: #409eff;
    color: #fff;
    line-height: 35px;
    text-align: center;
    font-size: 14px;
  }

  .upload-btn {
    width: 100%;
    height: 30px;
    line-height: 30px;
    font-size: 14px;
    background: #409eff;
    color: #fff;
  }

  .upload-box {
    border-radius: 5px;
    border: 1px solid #eee;
    margin-bottom: 10px;
    overflow: hidden;
    padding-bottom: 20px;
  }

  .search-input {
    border: 1px solid #eee;
    margin: 15px 0;
    border-radius: 25px;
    padding: 0 10px 0 10px;
    height: 25px;
    background: #f8f8f8;

    align-items: center;
  }

  .search-input input {
    outline: none;
    border: none;
    flex: 1;
    background: unset;
    margin-left: 5px;
    font-size: 12px;
  }

  .ht-content {
    padding: 15px;
  }

  .pj-dt-list {
    margin-top: 10px;
  }

  .more-icon {
    margin-left: 10px;
  }

  .el-input {
    width: auto;
    margin-left: 15px;
  }

  .pj-title /deep/ .el-input__icon {
    line-height: 20px;
  }

  .pj-title /deep/ .el-input__inner {
    height: 20px;
    line-height: 20px;
    width: 150px;
  }

  .file-info span {
    margin-right: 5px;
  }

  .file-name span {
    color: #04be02;
    text-underline: #04be02;
  }

  .file-name {
    text-align: left;
  }

  .file-info {
    color: #888;
    text-align: left;
    font-size: 10px;
    margin-top: 5px;
  }

  .file-list .file-item:last-child {
    border-bottom: none;
  }

  .file-item {
    padding: 10px 0;
    border-bottom: 1px solid #eee;
  }

  .ht-tip {
    font-size: 16px;
    padding: 10px;

  }

  .none-data {
    margin-top: 50px;
    height: 48vh;
    text-align: center;
  }

  .file-count {
    height: fit-content;
    color: #fff;
    padding: 3px;
    border-radius: 12px;
    line-height: 1;
    position: absolute;
    right: 0;
    margin-right: 10px;
    background: rgb(249, 200, 81);
  }

  .custom-tree-node {
    display: flex;
    flex-direction: row-reverse;
  }

  .checkItem {
    margin-top: 3px;
  }

  .pd-body /deep/ .vux-popup-dialog {
    background: #fff;
    max-width: 85%;
    overflow: hidden;
  }

  .main-title {
    margin: 10px;
    color: #c7c7c7;
  }

  .search-box input {
    height: 30px;
    border: none;
    font-size: 12px;
    padding-left: 5px;
  }

  .search-box {
    border: 1px solid #c7c7c7;
    border-radius: 3px;
    overflow: hidden;
    align-items: center;
    width: fit-content;
  }

  .search-btn {
    height: 30px;
    padding: 0 15px;
    font-size: 12px;
    line-height: 30px;
    background: #323A46;
    color: #fff;
  }

  .main-box {
    padding: 5px;
    background: #fff;
  }

  .fa-bars-div .fa {
    color: #000;
    font-size: 18px;
  }

  .fa-bars-div {
    position: fixed;
    top: 12px;
    z-index: 100;
  }

  .prj-name {
    color: #c7c7c7;
  }

  .prj-name, .prj-date {
    font-size: 8px;
    margin-top: 5px;
    color: #c7c7c7;
  }

  .pj-info4 {
    font-size: 8px;
    text-align: center;
  }

  .pj-head {
    padding: 15px 30px 15px 0;
    border-bottom: 1px solid #eee;
    margin-bottom: 15px;
  }

  .prj-files {
    word-wrap: break-word;
    word-break: break-all;
    white-space: pre-wrap;
  }

  .prj-id h3 {
    color: #000;
  }

  .prj-id {
    border-bottom: 1px solid #eee;
    padding-bottom: 10px;
    margin-bottom: 10px;
    color: #c7c7c7;
    font-size: 14px;
  }

  .pj-list-box {
    margin-top: 55px;
  }

  .art-thumb {
    width: 100%;
    max-height: 180px;
    border-radius: 5px;
    margin: 10px auto;
  }

  .art-thumb {
    width: 100%;
    max-height: 180px;
    border-radius: 5px;
    margin: 10px auto;
  }

  .pj-info1 {
    width: 130px;
  }

  .pj-info2 {
    text-align: center;
    width: 80px;
  }

  .pj-info3 {
    width: fit-content;
    color: #fff;
    background: rgb(255, 91, 91);
    font-size: 10px;
    border-radius: 3px;
    padding: 0 8px;
    height: fit-content;
  }

  .info-btn-box {
    align-items: center;
  }

  .info-btn {
    height: 35px;
    margin-left: 25px;
  }

  .pj-items >>> .el-checkbox.all-check {
    flex: 0;
    align-items: center;
    border-bottom: none;
  }

  .pj-info {
    flex: 1;
    padding-bottom: 10px;
    margin-bottom: 10px;
    border-bottom: 1px solid #e8e8e8;
  }

  .pj-items >>> .el-checkbox {
    display: flex;
    align-items: flex-start;
    margin-right: 0;
    flex: 1;
    padding: 15px 0px;
    border-bottom: 1px solid #eee;
  }

  .pj-items >>> .el-checkbox__label {
    display: flex;
    flex: 1;
    margin-top: -3px;
  }

  .pj-items >>> .el-checkbox__inner {
    color: #04be02;
    background-color: unset;
    border-color: #04be02;
  }

  .pj-items >>> .el-checkbox__input.is-checked .el-checkbox__inner, .el-checkbox__input.is-indeterminate .el-checkbox__inner {
    color: #04be02;
    background-color: #04be02;
    border-color: #04be02;
  }

  .pj-items >>> .el-checkbox__input.is-checked + .el-checkbox__label {
    color: #333;
    flex: 1;
  }

  .pj-items >>> .el-checkbox__input.is-checked .el-checkbox__inner, .el-checkbox__input.is-indeterminate .el-checkbox__inner {
    color: #04be02;
    background-color: #04be02;
    border-color: #04be02;
  }

  .pj-items >>> .el-checkbox__inner:hover {
    color: #04be02;
    border-color: #04be02;
  }

  .up-load-box {
    position: relative;
  }

  .upload-input {
    left: 0;
    position: absolute;
    opacity: 0;
  }

  .dt-title .fa {
    color: #c7c7c7;
  }

  .dt-title {
    align-items: center;
  }

  .pj-progress-load {
    margin-top: 5px;
  }

  .pj-progress-box {
    margin-top: 15px;
  }

  .pj-progress-num {
    color: #04be02;
    font-weight: 600;
  }

  .pj-src {
    color: #000;
    font-size: 12px;
    display: block;
    margin-top: 3px;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
  }

  .pj-mark {
    color: #c7c7c7;
    font-size: 12px;
    margin: 10px 0;
  }

  .pj-owner {
    font-size: 10px;
    color: #04be02;
    margin: 5px 0;
  }

  .pj-title {
    font-size: 14px;
  }

  .pj-state.ing {
    background: #04be02;
  }

  .pj-state {
    font-size: 10px;
    color: #fff;
    height: 16px;
    border-radius: 3px;
    line-height: 16px;
    padding: 0 3px;
    width: fit-content;
    min-width: 60px;
    text-align: center;
  }

  .pj-items {
    padding: 15px;
    background: #fff;
    border-radius: 5px;
    margin-bottom: 10px;
  }

  .pd-body {
    padding: 0 15px;
  }
</style>
